home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / config / pyr / pyr.md < prev    next >
Text File  |  1993-01-25  |  39KB  |  1,405 lines

  1. ;; GNU C machine description for Pyramid 90x, 9000, MIServer Series
  2. ;; Copyright (C) 1989, 1990 Free Software Foundation, Inc.
  3.  
  4. ;; This file is part of GNU CC.
  5.  
  6. ;; GNU CC is free software; you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation; either version 2, or (at your option)
  9. ;; any later version.
  10.  
  11. ;; GNU CC is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ;; GNU General Public License for more details.
  15.  
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with GNU CC; see the file COPYING.  If not, write to
  18. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. ;; Instruction patterns.  When multiple patterns apply,
  21. ;; the first one in the file is chosen.
  22. ;;
  23. ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
  24. ;;
  25. ;; cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
  26. ;; updates for most instructions.
  27.  
  28. ;; These comments are mostly obsolete.  Written for gcc version 1.XX.
  29. ;; * Try using define_insn instead of some peepholes in more places.
  30. ;; * Set REG_NOTES:REG_EQUIV for cvt[bh]w loads.  This would make the
  31. ;;   backward scan in sign_extend needless.
  32. ;; * Match (pc) (label_ref) case in peephole patterns.
  33. ;; * Should optimize
  34. ;;   "cmpX op1,op2;  b{eq,ne} LY;  ucmpX op1.op2;  b{lt,le,gt,ge} LZ"
  35. ;;   to
  36. ;;   "ucmpX op1,op2;  b{eq,ne} LY;  b{lt,le,gt,ge} LZ"
  37. ;;   by pre-scanning insn and running notice_update_cc for them.
  38. ;; * Is it necessary to do copy_rtx in the test and compare patterns?
  39. ;; * Fix true frame pointer omission.
  40. ;; * Make the jump tables contain branches, not addresses!  This would
  41. ;;   save us one instruction.
  42. ;; * Could the complicated scheme for compares be simplified, if we had
  43. ;;   no named cmpqi or cmphi patterns, and instead anonymous patterns for
  44. ;;   the less-than-word compare cases pyr can handle???
  45. ;; * The jump insn seems to accept more than just IR addressing.  Would
  46. ;;   we win by telling GCC?  Or can we use movw into the global reg which
  47. ;;   is a synonym for pc?
  48. ;; * More DImode patterns.
  49. ;; * Scan backwards in "zero_extendhisi2", "zero_extendqisi2" to find out
  50. ;;   if the extension can be omitted.
  51. ;; * "divmodsi" with Pyramid "ediv" insn.  Is it possible in rtl??
  52. ;; * Would "rcsp tmpreg; u?cmp[bh] op1_regdispl(tmpreg),op2" win in
  53. ;;   comparison with the two extensions and single test generated now?
  54. ;;   The rcsp insn could be expanded, and moved out of loops by the
  55. ;;   optimizer, making 1 (64 bit) insn of 3 (32 bit) insns in loops.
  56. ;;   The rcsp insn could be followed by an add insn, making non-displacement
  57. ;;   IR addressing sufficient.
  58.  
  59. ;______________________________________________________________________
  60. ;
  61. ;    Test and Compare Patterns.
  62. ;______________________________________________________________________
  63.  
  64. ; The argument for the rather complicated test and compare expansion
  65. ; scheme, is the irregular pyramid instructions for these operations.
  66. ; 1) Pyramid has different signed and unsigned compares.  2) HImode
  67. ; and QImode integers are memory-memory and immediate-memory only.  3)
  68. ; Unsigned HImode compares doesn't exist.  4) Only certain
  69. ; combinations of addresses are allowed for memory-memory compares.
  70. ; Whenever necessary, in order to fulfill these addressing
  71. ; constraints, the compare operands are swapped.
  72.  
  73. (define_expand "tstsi"
  74.   [(set (cc0)
  75.     (match_operand:SI 0 "general_operand" ""))]
  76.   "" "operands[0] = force_reg (SImode, operands[0]);")
  77.  
  78. (define_insn ""
  79.   [(set (cc0)
  80.     (compare (match_operand:SI 0 "memory_operand" "m")
  81.          (match_operand:SI 1 "memory_operand" "m")))]
  82.   "weird_memory_memory (operands[0], operands[1])"
  83.   "*
  84. {
  85.   rtx br_insn = NEXT_INSN (insn);
  86.   RTX_CODE br_code;
  87.  
  88.   if (GET_CODE (br_insn) != JUMP_INSN)
  89.     abort();
  90.   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
  91.  
  92.   weird_memory_memory (operands[0], operands[1]);
  93.  
  94.   if (swap_operands)
  95.     {
  96.       cc_status.flags = CC_REVERSED;
  97.       if (TRULY_UNSIGNED_COMPARE_P (br_code))
  98.     {
  99.       cc_status.mdep = CC_VALID_FOR_UNSIGNED;
  100.       return \"ucmpw %0,%1\";
  101.     }
  102.       return \"cmpw %0,%1\";
  103.     }
  104.  
  105.   if (TRULY_UNSIGNED_COMPARE_P (br_code))
  106.     {
  107.       cc_status.mdep = CC_VALID_FOR_UNSIGNED;
  108.       return \"ucmpw %1,%0\";
  109.     }
  110.   return \"cmpw %1,%0\";
  111. }")
  112.  
  113. (define_insn "cmpsi"
  114.   [(set (cc0)
  115.     (compare (match_operand:SI 0 "nonimmediate_operand" "r,g")
  116.          (match_operand:SI 1 "general_operand" "g,r")))]
  117.   ""
  118.   "*
  119. {
  120.   rtx br_insn = NEXT_INSN (insn);
  121.   RTX_CODE br_code;
  122.  
  123.   if (GET_CODE (br_insn) != JUMP_INSN)
  124.     abort();
  125.   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
  126.  
  127.   if (which_alternative != 0)
  128.     {
  129.       cc_status.flags = CC_REVERSED;
  130.       if (TRULY_UNSIGNED_COMPARE_P (br_code))
  131.     {
  132.       cc_status.mdep = CC_VALID_FOR_UNSIGNED;
  133.       return \"ucmpw %0,%1\";
  134.     }
  135.       return \"cmpw %0,%1\";
  136.     }
  137.  
  138.   if (TRULY_UNSIGNED_COMPARE_P (br_code))
  139.     {
  140.       cc_status.mdep = CC_VALID_FOR_UNSIGNED;
  141.       return \"ucmpw %1,%0\";
  142.     }
  143.   return \"cmpw %1,%0\";
  144. }")
  145.  
  146. (define_insn ""
  147.   [(set (cc0)
  148.     (match_operand:SI 0 "nonimmediate_operand" "r"))]
  149.   ""
  150.   "*
  151. {
  152. #if 0
  153.   cc_status.flags |= CC_NO_OVERFLOW;
  154.   return \"cmpw $0,%0\";
  155. #endif
  156.   rtx br_insn = NEXT_INSN (insn);
  157.   RTX_CODE br_code;
  158.  
  159.   if (GET_CODE (br_insn) != JUMP_INSN)
  160.     abort();
  161.   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
  162.  
  163.   if (TRULY_UNSIGNED_COMPARE_P (br_code))
  164.     {
  165.       cc_status.mdep = CC_VALID_FOR_UNSIGNED;
  166.       return \"ucmpw $0,%0\";
  167.     }
  168.   return \"mtstw %0,%0\";
  169. }")
  170.  
  171. (define_expand "cmphi"
  172.   [(set (cc0)
  173.     (compare (match_operand:HI 0 "nonimmediate_operand" "")
  174.          (match_operand:HI 1 "general_operand" "")))]
  175.   ""
  176.   "
  177. {
  178.   extern rtx test_op0, test_op1;  extern enum machine_mode test_mode;
  179.   test_op0 = copy_rtx (operands[0]);
  180.   test_op1 = copy_rtx (operands[1]);
  181.   test_mode = HImode;
  182.   DONE;
  183. }")
  184.  
  185. (define_expand "tsthi"
  186.   [(set (cc0)
  187.     (match_operand:HI 0 "nonimmediate_operand" ""))]
  188.   ""
  189.   "
  190. {
  191.   extern rtx test_op0;  extern enum machine_mode test_mode;
  192.   test_op0 = copy_rtx (operands[0]);
  193.   test_mode = HImode;
  194.   DONE;
  195. }")
  196.  
  197. (define_insn ""
  198.   [(set (cc0)
  199.     (compare (match_operand:HI 0 "memory_operand" "m")
  200.          (match_operand:HI 1 "memory_operand" "m")))]
  201.   "(!TRULY_UNSIGNED_COMPARE_P (GET_CODE (XEXP (SET_SRC (PATTERN (NEXT_INSN (insn))), 0))))
  202.    && weird_memory_memory (operands[0], operands[1])"
  203.   "*
  204. {
  205.   rtx br_insn = NEXT_INSN (insn);
  206.  
  207.   if (GET_CODE (br_insn) != JUMP_INSN)
  208.     abort();
  209.  
  210.   weird_memory_memory (operands[0], operands[1]);
  211.  
  212.   if (swap_operands)
  213.     {
  214.       cc_status.flags = CC_REVERSED;
  215.       return \"cmph %0,%1\";
  216.     }
  217.  
  218.   return \"cmph %1,%0\";
  219. }")
  220.  
  221. (define_insn ""
  222.   [(set (cc0)
  223.     (compare (match_operand:HI 0 "nonimmediate_operand" "r,m")
  224.          (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
  225.   "(!TRULY_UNSIGNED_COMPARE_P (GET_CODE (XEXP (SET_SRC (PATTERN (NEXT_INSN (insn))), 0))))
  226.    && (GET_CODE (operands[0]) != GET_CODE (operands[1]))"
  227.   "*
  228. {
  229.   rtx br_insn = NEXT_INSN (insn);
  230.  
  231.   if (GET_CODE (br_insn) != JUMP_INSN)
  232.     abort();
  233.  
  234.   if (which_alternative != 0)
  235.     {
  236.       cc_status.flags = CC_REVERSED;
  237.       return \"cmph %0,%1\";
  238.     }
  239.  
  240.   return \"cmph %1,%0\";
  241. }")
  242.  
  243. (define_expand "cmpqi"
  244.   [(set (cc0)
  245.     (compare (match_operand:QI 0 "nonimmediate_operand" "")
  246.          (match_operand:QI 1 "general_operand" "")))]
  247.   ""
  248.   "
  249. {
  250.   extern rtx test_op0, test_op1;  extern enum machine_mode test_mode;
  251.   test_op0 = copy_rtx (operands[0]);
  252.   test_op1 = copy_rtx (operands[1]);
  253.   test_mode = QImode;
  254.   DONE;
  255. }")
  256.  
  257. (define_expand "tstqi"
  258.   [(set (cc0)
  259.     (match_operand:QI 0 "nonimmediate_operand" ""))]
  260.   ""
  261.   "
  262. {
  263.   extern rtx test_op0;  extern enum machine_mode test_mode;
  264.   test_op0 = copy_rtx (operands[0]);
  265.   test_mode = QImode;
  266.   DONE;
  267. }")
  268.  
  269. (define_insn ""
  270.   [(set (cc0)
  271.     (compare (match_operand:QI 0 "memory_operand" "m")
  272.          (match_operand:QI 1 "memory_operand" "m")))]
  273.   "weird_memory_memory (operands[0], operands[1])"
  274.   "*
  275. {
  276.   rtx br_insn = NEXT_INSN (insn);
  277.   RTX_CODE br_code;
  278.  
  279.   if (GET_CODE (br_insn) != JUMP_INSN)
  280.     abort();
  281.   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
  282.  
  283.   weird_memory_memory (operands[0], operands[1]);
  284.  
  285.   if (swap_operands)
  286.     {
  287.       cc_status.flags = CC_REVERSED;
  288.       if (TRULY_UNSIGNED_COMPARE_P (br_code))
  289.     {
  290.       cc_status.mdep = CC_VALID_FOR_UNSIGNED;
  291.       return \"ucmpb %0,%1\";
  292.     }
  293.       return \"cmpb %0,%1\";
  294.     }
  295.  
  296.   if (TRULY_UNSIGNED_COMPARE_P (br_code))
  297.     {
  298.       cc_status.mdep = CC_VALID_FOR_UNSIGNED;
  299.       return \"ucmpb %1,%0\";
  300.     }
  301.   return \"cmpb %1,%0\";
  302. }")
  303.  
  304. (define_insn ""
  305.   [(set (cc0)
  306.     (compare (match_operand:QI 0 "nonimmediate_operand" "r,m")
  307.          (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
  308.   "(GET_CODE (operands[0]) != GET_CODE (operands[1]))"
  309.   "*
  310. {
  311.   rtx br_insn = NEXT_INSN (insn);
  312.   RTX_CODE br_code;
  313.  
  314.   if (GET_CODE (br_insn) != JUMP_INSN)
  315.     abort();
  316.   br_code =  GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
  317.  
  318.   if (which_alternative != 0)
  319.     {
  320.       cc_status.flags = CC_REVERSED;
  321.       if (TRULY_UNSIGNED_COMPARE_P (br_code))
  322.     {
  323.       cc_status.mdep = CC_VALID_FOR_UNSIGNED;
  324.       return \"ucmpb %0,%1\";
  325.     }
  326.       return \"cmpb %0,%1\";
  327.     }
  328.  
  329.   if (TRULY_UNSIGNED_COMPARE_P (br_code))
  330.     {
  331.       cc_status.mdep = CC_VALID_FOR_UNSIGNED;
  332.       return \"ucmpb %1,%0\";
  333.     }
  334.   return \"cmpb %1,%0\";
  335. }")
  336.  
  337. (define_expand "bgt"
  338.   [(set (pc) (if_then_else (gt (cc0) (const_int 0))
  339.                (label_ref (match_operand 0 "" "")) (pc)))]
  340.   "" "extend_and_branch (SIGN_EXTEND);")
  341.  
  342. (define_expand "blt"
  343.   [(set (pc) (if_then_else (lt (cc0) (const_int 0))
  344.                (label_ref (match_operand 0 "" "")) (pc)))]
  345.   "" "extend_and_branch (SIGN_EXTEND);")
  346.  
  347. (define_expand "bge"
  348.   [(set (pc) (if_then_else (ge (cc0) (const_int 0))
  349.                (label_ref (match_operand 0 "" "")) (pc)))]
  350.   "" "extend_and_branch (SIGN_EXTEND);")
  351.  
  352. (define_expand "ble"
  353.   [(set (pc) (if_then_else (le (cc0) (const_int 0))
  354.                (label_ref (match_operand 0 "" "")) (pc)))]
  355.   "" "extend_and_branch (SIGN_EXTEND);")
  356.  
  357. (define_expand "beq"
  358.   [(set (pc) (if_then_else (eq (cc0) (const_int 0))
  359.                (label_ref (match_operand 0 "" "")) (pc)))]
  360.   "" "extend_and_branch (SIGN_EXTEND);")
  361.  
  362. (define_expand "bne"
  363.   [(set (pc) (if_then_else (ne (cc0) (const_int 0))
  364.                (label_ref (match_operand 0 "" "")) (pc)))]
  365.   "" "extend_and_branch (SIGN_EXTEND);")
  366.  
  367. (define_expand "bgtu"
  368.   [(set (pc) (if_then_else (gtu (cc0) (const_int 0))
  369.                (label_ref (match_operand 0 "" "")) (pc)))]
  370.   "" "extend_and_branch (ZERO_EXTEND);")
  371.  
  372. (define_expand "bltu"
  373.   [(set (pc) (if_then_else (ltu (cc0) (const_int 0))
  374.                (label_ref (match_operand 0 "" "")) (pc)))]
  375.   "" "extend_and_branch (ZERO_EXTEND);")
  376.  
  377. (define_expand "bgeu"
  378.   [(set (pc) (if_then_else (geu (cc0) (const_int 0))
  379.                (label_ref (match_operand 0 "" "")) (pc)))]
  380.   "" "extend_and_branch (ZERO_EXTEND);")
  381.  
  382. (define_expand "bleu"
  383.   [(set (pc) (if_then_else (leu (cc0) (const_int 0))
  384.                (label_ref (match_operand 0 "" "")) (pc)))]
  385.   "" "extend_and_branch (ZERO_EXTEND);")
  386.  
  387. (define_insn "cmpdf"
  388.   [(set (cc0)
  389.     (compare (match_operand:DF 0 "register_operand" "r")
  390.          (match_operand:DF 1 "register_operand" "r")))]
  391.   ""
  392.   "cmpd %1,%0")
  393.  
  394. (define_insn "cmpsf"
  395.   [(set (cc0)
  396.     (compare (match_operand:SF 0 "register_operand" "r")
  397.          (match_operand:SF 1 "register_operand" "r")))]
  398.   ""
  399.   "cmpf %1,%0")
  400.  
  401. (define_insn "tstdf"
  402.   [(set (cc0)
  403.            (match_operand:DF 0 "register_operand" "r"))]
  404.   ""
  405.   "mtstd %0,%0")
  406.  
  407. (define_insn "tstsf"
  408.   [(set (cc0)
  409.            (match_operand:SF 0 "register_operand" "r"))]
  410.   ""
  411.   "mtstf %0,%0")
  412.  
  413. ;______________________________________________________________________
  414. ;
  415. ;    Fixed-point Arithmetic.
  416. ;______________________________________________________________________
  417.  
  418. (define_insn "addsi3"
  419.   [(set (match_operand:SI 0 "register_operand" "=r,!r")
  420.     (plus:SI (match_operand:SI 1 "general_operand" "%0,r")
  421.          (match_operand:SI 2 "general_operand" "g,rJ")))]
  422.   ""
  423.   "*
  424. {
  425.   if (which_alternative == 0)
  426.     return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 32
  427.         ? \"subw %n2,%0\" : \"addw %2,%0\");
  428.   else
  429.     {
  430.       forget_cc_if_dependent (operands[0]);
  431.       return \"mova %a2[%1*1],%0\";
  432.     }
  433. }")
  434.  
  435. (define_insn "subsi3"
  436.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  437.     (minus:SI (match_operand:SI 1 "general_operand" "0,g")
  438.           (match_operand:SI 2 "general_operand" "g,0")))]
  439.   ""
  440.   "* return (which_alternative == 0) ? \"subw %2,%0\" : \"rsubw %1,%0\";")
  441.  
  442. (define_insn "mulsi3"
  443.   [(set (match_operand:SI 0 "register_operand" "=r")
  444.     (mult:SI (match_operand:SI 1 "general_operand" "%0")
  445.          (match_operand:SI 2 "general_operand" "g")))]
  446.   ""
  447.   "mulw %2,%0")
  448.  
  449. (define_insn "divsi3"
  450.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  451.     (div:SI (match_operand:SI 1 "general_operand" "0,g")
  452.         (match_operand:SI 2 "general_operand" "g,0")))]
  453.   ""
  454.   "* return (which_alternative == 0) ? \"divw %2,%0\" : \"rdivw %1,%0\";")
  455.  
  456. (define_insn "udivsi3"
  457.   [(set (match_operand:SI 0 "register_operand" "=r")
  458.     (udiv:SI (match_operand:SI 1 "register_operand" "0")
  459.          (match_operand:SI 2 "general_operand" "g")))]
  460.   ""
  461.   "udivw %2,%0")
  462.  
  463. (define_insn "modsi3"
  464.   [(set (match_operand:SI 0 "register_operand" "=r")
  465.     (mod:SI (match_operand:SI 1 "register_operand" "0")
  466.         (match_operand:SI 2 "general_operand" "g")))]
  467.   ""
  468.   "modw %2,%0")
  469.  
  470. (define_insn "umodsi3"
  471.   [(set (match_operand:SI 0 "register_operand" "=r")
  472.     (umod:SI (match_operand:SI 1 "register_operand" "0")
  473.          (match_operand:SI 2 "general_operand" "g")))]
  474.   ""
  475.   "umodw %2,%0")
  476.  
  477. (define_insn "negsi2"
  478.   [(set (match_operand:SI 0 "register_operand" "=r")
  479.     (neg:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  480.   ""
  481.   "mnegw %1,%0")
  482.  
  483. (define_insn "one_cmplsi2"
  484.   [(set (match_operand:SI 0 "register_operand" "=r")
  485.     (not:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  486.   ""
  487.   "mcomw %1,%0")
  488.  
  489. (define_insn "abssi2"
  490.   [(set (match_operand:SI 0 "register_operand" "=r")
  491.     (abs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  492.   ""
  493.   "mabsw %1,%0")
  494.  
  495. ;______________________________________________________________________
  496. ;
  497. ;    Floating-point Arithmetic.
  498. ;______________________________________________________________________
  499.  
  500. (define_insn "adddf3"
  501.   [(set (match_operand:DF 0 "register_operand" "=r")
  502.     (plus:DF (match_operand:DF 1 "register_operand" "%0")
  503.          (match_operand:DF 2 "register_operand" "r")))]
  504.   ""
  505.   "addd %2,%0")
  506.  
  507. (define_insn "addsf3"
  508.   [(set (match_operand:SF 0 "register_operand" "=r")
  509.     (plus:SF (match_operand:SF 1 "register_operand" "%0")
  510.          (match_operand:SF 2 "register_operand" "r")))]
  511.   ""
  512.   "addf %2,%0")
  513.  
  514. (define_insn "subdf3"
  515.   [(set (match_operand:DF 0 "register_operand" "=r")
  516.     (minus:DF (match_operand:DF 1 "register_operand" "0")
  517.           (match_operand:DF 2 "register_operand" "r")))]
  518.   ""
  519.   "subd %2,%0")
  520.  
  521. (define_insn "subsf3"
  522.   [(set (match_operand:SF 0 "register_operand" "=r")
  523.     (minus:SF (match_operand:SF 1 "register_operand" "0")
  524.           (match_operand:SF 2 "register_operand" "r")))]
  525.   ""
  526.   "subf %2,%0")
  527.  
  528. (define_insn "muldf3"
  529.   [(set (match_operand:DF 0 "register_operand" "=r")
  530.     (mult:DF (match_operand:DF 1 "register_operand" "%0")
  531.          (match_operand:DF 2 "register_operand" "r")))]
  532.   ""
  533.   "muld %2,%0")
  534.  
  535. (define_insn "mulsf3"
  536.   [(set (match_operand:SF 0 "register_operand" "=r")
  537.     (mult:SF (match_operand:SF 1 "register_operand" "%0")
  538.          (match_operand:SF 2 "register_operand" "r")))]
  539.   ""
  540.   "mulf %2,%0")
  541.  
  542. (define_insn "divdf3"
  543.   [(set (match_operand:DF 0 "register_operand" "=r")
  544.     (div:DF (match_operand:DF 1 "register_operand" "0")
  545.         (match_operand:DF 2 "register_operand" "r")))]
  546.   ""
  547.   "divd %2,%0")
  548.  
  549. (define_insn "divsf3"
  550.   [(set (match_operand:SF 0 "register_operand" "=r")
  551.     (div:SF (match_operand:SF 1 "register_operand" "0")
  552.         (match_operand:SF 2 "register_operand" "r")))]
  553.   ""
  554.   "divf %2,%0")
  555.  
  556. (define_insn "negdf2"
  557.   [(set (match_operand:DF 0 "register_operand" "=r")
  558.     (neg:DF (match_operand:DF 1 "register_operand" "r")))]
  559.   ""
  560.   "mnegd %1,%0")
  561.  
  562. (define_insn "negsf2"
  563.   [(set (match_operand:SF 0 "register_operand" "=r")
  564.     (neg:SF (match_operand:SF 1 "register_operand" "r")))]
  565.   ""
  566.   "mnegf %1,%0")
  567.  
  568. (define_insn "absdf2"
  569.   [(set (match_operand:DF 0 "register_operand" "=r")
  570.     (abs:DF (match_operand:DF 1 "register_operand" "r")))]
  571.   ""
  572.   "mabsd %1,%0")
  573.  
  574. (define_insn "abssf2"
  575.   [(set (match_operand:SF 0 "register_operand" "=r")
  576.     (abs:SF (match_operand:SF 1 "register_operand" "r")))]
  577.   ""
  578.   "mabsf %1,%0")
  579.  
  580. ;______________________________________________________________________
  581. ;
  582. ;    Logical and Shift Instructions.
  583. ;______________________________________________________________________
  584.  
  585. (define_insn ""
  586.   [(set (cc0)
  587.     (and:SI (match_operand:SI 0 "general_operand" "%r")
  588.         (match_operand:SI 1 "general_operand" "g")))]
  589.   ""
  590.   "*
  591. {
  592.   cc_status.flags |= CC_NO_OVERFLOW;
  593.   return \"bitw %1,%0\";
  594. }")
  595.  
  596. (define_insn "andsi3"
  597.   [(set (match_operand:SI 0 "register_operand" "=r,r")
  598.     (and:SI (match_operand:SI 1 "general_operand" "%0,r")
  599.         (match_operand:SI 2 "general_operand" "g,K")))]
  600.   ""
  601.   "*
  602. {
  603.   if (which_alternative == 0)
  604.     return \"andw %2,%0\";
  605.  
  606.   cc_status.flags = CC_NOT_NEGATIVE;
  607.   return (INTVAL (operands[2]) == 255
  608.       ? \"movzbw %1,%0\" : \"movzhw %1,%0\");
  609. }")
  610.  
  611. (define_insn ""
  612.   [(set (match_operand:SI 0 "register_operand" "=r")
  613.     (and:SI (not:SI (match_operand:SI 1 "general_operand" "g"))
  614.         (match_operand:SI 2 "register_operand" "0")))]
  615.   ""
  616.   "bicw %1,%0")
  617.  
  618. (define_insn "iorsi3"
  619.   [(set (match_operand:SI 0 "register_operand" "=r")
  620.     (ior:SI (match_operand:SI 1 "general_operand" "%0")
  621.         (match_operand:SI 2 "general_operand" "g")))]
  622.   ""
  623.   "orw %2,%0")
  624.  
  625. (define_insn "xorsi3"
  626.   [(set (match_operand:SI 0 "register_operand" "=r")
  627.     (xor:SI (match_operand:SI 1 "general_operand" "%0")
  628.         (match_operand:SI 2 "general_operand" "g")))]
  629.   ""
  630.   "xorw %2,%0")
  631.  
  632. ; The arithmetic left shift instructions work strangely on pyramids.
  633. ; They fail to modify the sign bit.  Therefore, use logic shifts.
  634.  
  635. (define_insn "ashlsi3"
  636.   [(set (match_operand:SI 0 "register_operand" "=r")
  637.     (ashift:SI (match_operand:SI 1 "register_operand" "0")
  638.            (match_operand:SI 2 "general_operand" "rnm")))]
  639.   ""
  640.   "*
  641. {
  642.   extern char *output_shift ();
  643.   return output_shift (\"lshlw %2,%0\", operands[2], 32);
  644. }")
  645.  
  646. (define_insn "ashrsi3"
  647.   [(set (match_operand:SI 0 "register_operand" "=r")
  648.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
  649.              (match_operand:SI 2 "general_operand" "rnm")))]
  650.   ""
  651.   "*
  652. {
  653.   extern char *output_shift ();
  654.   return output_shift (\"ashrw %2,%0\", operands[2], 32);
  655. }")
  656.  
  657. (define_insn "ashrdi3"
  658.   [(set (match_operand:DI 0 "register_operand" "=r")
  659.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
  660.              (match_operand:SI 2 "general_operand" "rnm")))]
  661.   ""
  662.   "*
  663. {
  664.   extern char *output_shift ();
  665.   return output_shift (\"ashrl %2,%0\", operands[2], 64);
  666. }")
  667.  
  668. (define_insn "lshrsi3"
  669.   [(set (match_operand:SI 0 "register_operand" "=r")
  670.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
  671.              (match_operand:SI 2 "general_operand" "rnm")))]
  672.   ""
  673.   "*
  674. {
  675.   extern char *output_shift ();
  676.   return output_shift (\"lshrw %2,%0\", operands[2], 32);
  677. }")
  678.  
  679. (define_insn "rotlsi3"
  680.   [(set (match_operand:SI 0 "register_operand" "=r")
  681.     (rotate:SI (match_operand:SI 1 "register_operand" "0")
  682.            (match_operand:SI 2 "general_operand" "rnm")))]
  683.   ""
  684.   "*
  685. {
  686.   extern char *output_shift ();
  687.   return output_shift (\"rotlw %2,%0\", operands[2], 32);
  688. }")
  689.  
  690. (define_insn "rotrsi3"
  691.   [(set (match_operand:SI 0 "register_operand" "=r")
  692.     (rotatert:SI (match_operand:SI 1 "register_operand" "0")
  693.              (match_operand:SI 2 "general_operand" "rnm")))]
  694.   ""
  695.   "*
  696. {
  697.   extern char *output_shift ();
  698.   return output_shift (\"rotrw %2,%0\", operands[2], 32);
  699. }")
  700.  
  701. ;______________________________________________________________________
  702. ;
  703. ;    Fixed and Floating Moves.
  704. ;______________________________________________________________________
  705.  
  706. ;; If the destination is a memory operand, indexed source operands are
  707. ;; disallowed.  Big DImode constants are always loaded into a reg pair,
  708. ;; although offsettable memory addresses really could be dealt with.
  709.  
  710. (define_insn ""
  711.   [(set (match_operand:DI 0 "memory_operand" "=m")
  712.     (match_operand:DI 1 "nonindexed_operand" "gF"))]
  713.   "(GET_CODE (operands[1]) == CONST_DOUBLE
  714.      ? ((CONST_DOUBLE_HIGH (operands[1]) == 0
  715.      && CONST_DOUBLE_LOW (operands[1]) >= 0)
  716.     || (CONST_DOUBLE_HIGH (operands[1]) == -1
  717.         && CONST_DOUBLE_LOW (operands[1]) < 0))
  718.      : 1)"
  719.   "*
  720. {
  721.   if (GET_CODE (operands[1]) == CONST_DOUBLE)
  722.     operands[1] = gen_rtx (CONST_INT, VOIDmode,
  723.                       CONST_DOUBLE_LOW (operands[1]));
  724.   return \"movl %1,%0\";
  725. }")
  726.  
  727. ;; Force the destination to a register, so all source operands are allowed.
  728.  
  729. (define_insn "movdi"
  730.   [(set (match_operand:DI 0 "general_operand" "=r")
  731.     (match_operand:DI 1 "general_operand" "gF"))]
  732.   ""
  733.   "*
  734. {
  735.   extern char *output_move_double ();
  736.   return output_move_double (operands);
  737. }")
  738.  
  739. ;; If the destination is a memory address, indexed source operands are
  740. ;; disallowed.
  741.  
  742. (define_insn ""
  743.   [(set (match_operand:SI 0 "memory_operand" "=m")
  744.     (match_operand:SI 1 "nonindexed_operand" "g"))]
  745.   ""
  746.   "movw %1,%0")
  747.  
  748. ;; Force the destination to a register, so all source operands are allowed.
  749.  
  750. (define_insn "movsi"
  751.   [(set (match_operand:SI 0 "general_operand" "=r")
  752.     (match_operand:SI 1 "general_operand" "g"))]
  753.   ""
  754.   "movw %1,%0")
  755.  
  756. ;; If the destination is a memory address, indexed source operands are
  757. ;; disallowed.
  758.  
  759. (define_insn ""
  760.   [(set (match_operand:HI 0 "memory_operand" "=m")
  761.     (match_operand:HI 1 "nonindexed_operand" "g"))]
  762.   ""
  763.   "*
  764. {
  765.   if (REG_P (operands[1]))
  766.     return \"cvtwh %1,%0\";        /* reg -> mem */
  767.   else
  768.     return \"movh %1,%0\";        /* mem imm -> mem */
  769. }")
  770.  
  771. ;; Force the destination to a register, so all source operands are allowed.
  772.  
  773. (define_insn "movhi"
  774.   [(set (match_operand:HI 0 "general_operand" "=r")
  775.     (match_operand:HI 1 "general_operand" "g"))]
  776.   ""
  777.   "*
  778. {
  779.   if (GET_CODE (operands[1]) != MEM)
  780.     return \"movw %1,%0\";        /* reg imm -> reg  */
  781.   return \"cvthw %1,%0\";        /* mem -> reg */
  782. }")
  783.  
  784. ;; If the destination is a memory address, indexed source operands are
  785. ;; disallowed.
  786.  
  787. (define_insn ""
  788.   [(set (match_operand:QI 0 "memory_operand" "=m")
  789.     (match_operand:QI 1 "nonindexed_operand" "g"))]
  790.   ""
  791.   "*
  792. {
  793.   if (REG_P (operands[1]))
  794.     return \"cvtwb %1,%0\";        /* reg -> mem */
  795.   else
  796.     return \"movb %1,%0\";        /* mem imm -> mem */
  797. }")
  798.  
  799. ;; Force the destination to a register, so all source operands are allowed.
  800.  
  801. (define_insn "movqi"
  802.   [(set (match_operand:QI 0 "general_operand" "=r")
  803.     (match_operand:QI 1 "general_operand" "g"))]
  804.   ""
  805.   "*
  806. {
  807.   if (GET_CODE (operands[1]) != MEM)
  808.     return \"movw %1,%0\";        /* reg imm -> reg  */
  809.   return \"cvtbw %1,%0\";        /* mem -> reg */
  810. }")
  811.  
  812. ;; If the destination is a memory address, indexed source operands are
  813. ;; disallowed.
  814.  
  815. (define_insn ""
  816.   [(set (match_operand:DF 0 "memory_operand" "=m")
  817.     (match_operand:DF 1 "nonindexed_operand" "g"))]
  818.   "GET_CODE (operands[1]) != CONST_DOUBLE"
  819.   "movl %1,%0")
  820.  
  821. ;; Force the destination to a register, so all source operands are allowed.
  822.  
  823. (define_insn "movdf"
  824.   [(set (match_operand:DF 0 "general_operand" "=r")
  825.     (match_operand:DF 1 "general_operand" "gF"))]
  826.   ""
  827.   "*
  828. {
  829.   extern char *output_move_double ();
  830.   return output_move_double (operands);
  831. }")
  832.  
  833. ;; If the destination is a memory address, indexed source operands are
  834. ;; disallowed.
  835.  
  836. (define_insn ""
  837.   [(set (match_operand:SF 0 "memory_operand" "=m")
  838.     (match_operand:SF 1 "nonindexed_operand" "g"))]
  839.   ""
  840.   "movw %1,%0")
  841.  
  842. ;; Force the destination to a register, so all source operands are allowed.
  843.  
  844. (define_insn "movsf"
  845.   [(set (match_operand:SF 0 "general_operand" "=r")
  846.     (match_operand:SF 1 "general_operand" "g"))]
  847.   ""
  848.   "movw %1,%0")
  849.  
  850. (define_insn ""
  851.   [(set (match_operand:SI 0 "register_operand" "=r")
  852.     (match_operand:QI 1 "address_operand" "p"))]
  853.   ""
  854.   "*
  855. {
  856.   forget_cc_if_dependent (operands[0]);
  857.   return \"mova %a1,%0\";
  858. }")
  859.  
  860. ;______________________________________________________________________
  861. ;
  862. ;    Conversion patterns.
  863. ;______________________________________________________________________
  864.  
  865. ;; The trunc patterns are used only when non compile-time constants are used.
  866.  
  867. (define_insn "truncsiqi2"
  868.   [(set (match_operand:QI 0 "register_operand" "=r")
  869.     (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  870.   ""
  871.   "*
  872. {
  873.   if (REG_P (operands[0]) && REG_P (operands[1])
  874.       && REGNO (operands[0]) == REGNO (operands[1]))
  875.     {
  876.       cc_status = cc_prev_status;
  877.       return \"\";
  878.     }
  879.   forget_cc_if_dependent (operands[0]);
  880.   return \"movw %1,%0\";
  881. }")
  882.  
  883. (define_insn "truncsihi2"
  884.   [(set (match_operand:HI 0 "register_operand" "=r")
  885.     (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  886.   ""
  887.   "*
  888. {
  889.   if (REG_P (operands[0]) && REG_P (operands[1])
  890.       && REGNO (operands[0]) == REGNO (operands[1]))
  891.     {
  892.       cc_status = cc_prev_status;
  893.       return \"\";
  894.     }
  895.   forget_cc_if_dependent (operands[0]);
  896.   return \"movw %1,%0\";
  897. }")
  898.  
  899. (define_insn "extendhisi2"
  900.   [(set (match_operand:SI 0 "general_operand" "=r,m")
  901.     (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm,r")))]
  902.   ""
  903.   "*
  904. {
  905.   extern int optimize;
  906.   if (optimize && REG_P (operands[0]) && REG_P (operands[1])
  907.       && REGNO (operands[0]) == REGNO (operands[1])
  908.       && already_sign_extended (insn, HImode, operands[0]))
  909.     {
  910.       cc_status = cc_prev_status;
  911.       return \"\";
  912.     }
  913.   return \"cvthw %1,%0\";
  914. }")
  915.  
  916. (define_insn "extendqisi2"
  917.   [(set (match_operand:SI 0 "general_operand" "=r,m")
  918.     (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm,r")))]
  919.   ""
  920.   "*
  921. {
  922.   extern int optimize;
  923.   if (optimize && REG_P (operands[0]) && REG_P (operands[1])
  924.       && REGNO (operands[0]) == REGNO (operands[1])
  925.       && already_sign_extended (insn, QImode, operands[0]))
  926.     {
  927.       cc_status = cc_prev_status;
  928.       return \"\";
  929.     }
  930.   return \"cvtbw %1,%0\";
  931. }")
  932.  
  933. ; Pyramid doesn't have insns *called* "cvtbh" or "movzbh".
  934. ; But we can cvtbw/movzbw into a register, where there is no distinction
  935. ; between words and halfwords.
  936.  
  937. (define_insn "extendqihi2"
  938.   [(set (match_operand:HI 0 "register_operand" "=r")
  939.     (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
  940.   ""
  941.   "cvtbw %1,%0")
  942.  
  943. (define_insn "zero_extendhisi2"
  944.   [(set (match_operand:SI 0 "register_operand" "=r")
  945.     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  946.   ""
  947.   "*
  948. {
  949.   cc_status.flags = CC_NOT_NEGATIVE;
  950.   return \"movzhw %1,%0\";
  951. }")
  952.  
  953. (define_insn "zero_extendqisi2"
  954.   [(set (match_operand:SI 0 "register_operand" "=r")
  955.     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
  956.   ""
  957.   "*
  958. {
  959.   cc_status.flags = CC_NOT_NEGATIVE;
  960.   return \"movzbw %1,%0\";
  961. }")
  962.  
  963. (define_insn "zero_extendqihi2"
  964.   [(set (match_operand:HI 0 "register_operand" "=r")
  965.     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
  966.   ""
  967.   "*
  968. {
  969.   cc_status.flags = CC_NOT_NEGATIVE;
  970.   return \"movzbw %1,%0\";
  971. }")
  972.  
  973. (define_insn "extendsfdf2"
  974.   [(set (match_operand:DF 0 "general_operand" "=&r,m")
  975.     (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "rm,r")))]
  976.   ""
  977.   "cvtfd %1,%0")
  978.  
  979. (define_insn "truncdfsf2"
  980.   [(set (match_operand:SF 0 "general_operand" "=&r,m")
  981.     (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "rm,r")))]
  982.   ""
  983.   "cvtdf %1,%0")
  984.  
  985. (define_insn "floatsisf2"
  986.   [(set (match_operand:SF 0 "general_operand" "=&r,m")
  987.     (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
  988.   ""
  989.   "cvtwf %1,%0")
  990.  
  991. (define_insn "floatsidf2"
  992.   [(set (match_operand:DF 0 "general_operand" "=&r,m")
  993.     (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm,r")))]
  994.   ""
  995.   "cvtwd %1,%0")
  996.  
  997. (define_insn "fix_truncsfsi2"
  998.   [(set (match_operand:SI 0 "general_operand" "=&r,m")
  999.     (fix:SI (fix:SF (match_operand:SF 1 "nonimmediate_operand" "rm,r"))))]
  1000.   ""
  1001.   "cvtfw %1,%0")
  1002.  
  1003. (define_insn "fix_truncdfsi2"
  1004.   [(set (match_operand:SI 0 "general_operand" "=&r,m")
  1005.     (fix:SI (fix:DF (match_operand:DF 1 "nonimmediate_operand" "rm,r"))))]
  1006.   ""
  1007.   "cvtdw %1,%0")
  1008.  
  1009. ;______________________________________________________________________
  1010. ;
  1011. ;    Flow Control Patterns.
  1012. ;______________________________________________________________________
  1013.  
  1014. ;; Prefer "br" to "jump" for unconditional jumps, since it's faster.
  1015. ;; (The assembler can manage with out-of-range branches.)
  1016.  
  1017. (define_insn "jump"
  1018.   [(set (pc)
  1019.     (label_ref (match_operand 0 "" "")))]
  1020.   ""
  1021.   "br %l0")
  1022.  
  1023. (define_insn ""
  1024.   [(set (pc)
  1025.     (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
  1026.               (label_ref (match_operand 1 "" ""))
  1027.               (pc)))]
  1028.   ""
  1029.   "*
  1030. {
  1031.   extern int optimize;
  1032.   if (optimize)
  1033.     switch (GET_CODE (operands[0]))
  1034.       {
  1035.       case EQ: case NE:
  1036.     break;
  1037.       case LT: case LE: case GE: case GT:
  1038.     if (cc_prev_status.mdep == CC_VALID_FOR_UNSIGNED)
  1039.       return 0;
  1040.     break;
  1041.       case LTU: case LEU: case GEU: case GTU:
  1042.     if (cc_prev_status.mdep != CC_VALID_FOR_UNSIGNED)
  1043.       return 0;
  1044.     break;
  1045.       }
  1046.  
  1047.   return \"b%N0 %l1\";
  1048. }")
  1049.  
  1050. (define_insn ""
  1051.   [(set (pc)
  1052.     (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
  1053.               (pc)
  1054.               (label_ref (match_operand 1 "" ""))))]
  1055.   ""
  1056.   "*
  1057. {
  1058.   extern int optimize;
  1059.   if (optimize)
  1060.     switch (GET_CODE (operands[0]))
  1061.       {
  1062.       case EQ: case NE:
  1063.     break;
  1064.       case LT: case LE: case GE: case GT:
  1065.     if (cc_prev_status.mdep == CC_VALID_FOR_UNSIGNED)
  1066.       return 0;
  1067.     break;
  1068.       case LTU: case LEU: case GEU: case GTU:
  1069.     if (cc_prev_status.mdep != CC_VALID_FOR_UNSIGNED)
  1070.       return 0;
  1071.     break;
  1072.       }
  1073.  
  1074.   return \"b%C0 %l1\";
  1075. }")
  1076.  
  1077. (define_insn "call"
  1078.   [(call (match_operand:QI 0 "memory_operand" "m")
  1079.      (match_operand:SI 1 "immediate_operand" "n"))]
  1080.   ""
  1081.   "call %0")
  1082.  
  1083. (define_insn "call_value"
  1084.   [(set (match_operand 0 "" "=r")
  1085.     (call (match_operand:QI 1 "memory_operand" "m")
  1086.           (match_operand:SI 2 "immediate_operand" "n")))]
  1087.   ;; Operand 2 not really used on Pyramid architecture.
  1088.   ""
  1089.   "call %1")
  1090.  
  1091. (define_insn "return"
  1092.   [(return)]
  1093.   ""
  1094.   "*
  1095. {
  1096.   if (get_frame_size () + current_function_pretend_args_size
  1097.       + current_function_args_size != 0
  1098.       || current_function_calls_alloca)
  1099.     {
  1100.       int dealloc_size = current_function_pretend_args_size;
  1101.       if (current_function_pops_args)
  1102.         dealloc_size += current_function_args_size;
  1103.       operands[0] = gen_rtx (CONST_INT, VOIDmode, dealloc_size);
  1104.       return \"retd %0\";
  1105.     }
  1106.   else
  1107.     return \"ret\";
  1108. }")
  1109.  
  1110. (define_insn "tablejump"
  1111.   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
  1112.    (use (label_ref (match_operand 1 "" "")))]
  1113.   ""
  1114.   "jump (%0)")
  1115.  
  1116. (define_insn "nop"
  1117.   [(const_int 0)]
  1118.   ""
  1119.   "movw gr0,gr0  # nop")
  1120.  
  1121. ;______________________________________________________________________
  1122. ;
  1123. ;    Peep-hole Optimization Patterns.
  1124. ;______________________________________________________________________
  1125.  
  1126. ;; Optimize fullword move followed by a test of the moved value.
  1127.  
  1128. (define_peephole
  1129.   [(set (match_operand:SI 0 "register_operand" "=r")
  1130.     (match_operand:SI 1 "nonimmediate_operand" "rm"))
  1131.    (set (cc0) (match_operand:SI 2 "nonimmediate_operand" "rm"))]
  1132.   "rtx_equal_p (operands[2], operands[0])
  1133.    || rtx_equal_p (operands[2], operands[1])"
  1134.   "*
  1135.   cc_status.flags |= CC_NO_OVERFLOW;
  1136.   return \"mtstw %1,%0\";
  1137. ")
  1138.  
  1139. ;; Same for HI and QI mode move-test as well.
  1140.  
  1141. (define_peephole
  1142.   [(set (match_operand:HI 0 "register_operand" "=r")
  1143.     (match_operand:HI 1 "nonimmediate_operand" "rm"))
  1144.    (set (match_operand:SI 2 "register_operand" "=r")
  1145.     (sign_extend:SI (match_operand:HI 3 "nonimmediate_operand" "rm")))
  1146.    (set (cc0) (match_dup 2))]
  1147.   "dead_or_set_p (insn, operands[2])
  1148.    && (rtx_equal_p (operands[3], operands[0])
  1149.        || rtx_equal_p (operands[3], operands[1]))"
  1150.   "*
  1151.   cc_status.flags |= CC_NO_OVERFLOW;
  1152.   return \"cvthw %1,%0\";
  1153. ")
  1154.  
  1155. (define_peephole
  1156.   [(set (match_operand:QI 0 "register_operand" "=r")
  1157.     (match_operand:QI 1 "nonimmediate_operand" "rm"))
  1158.    (set (match_operand:SI 2 "register_operand" "=r")
  1159.     (sign_extend:SI (match_operand:QI 3 "nonimmediate_operand" "rm")))
  1160.    (set (cc0) (match_dup 2))]
  1161.   "dead_or_set_p (insn, operands[2])
  1162.    && (rtx_equal_p (operands[3], operands[0])
  1163.        || rtx_equal_p (operands[3], operands[1]))"
  1164.   "*
  1165.   cc_status.flags |= CC_NO_OVERFLOW;
  1166.   return \"cvtbw %1,%0\";
  1167. ")
  1168.  
  1169. ;; Optimize loops with an incremented/decremented variable.
  1170.  
  1171. (define_peephole
  1172.   [(set (match_operand:SI 0 "register_operand" "=r")
  1173.     (plus:SI (match_dup 0)
  1174.          (const_int -1)))
  1175.    (set (cc0)
  1176.     (compare (match_operand:SI 1 "register_operand" "r")
  1177.          (match_operand:SI 2 "nonmemory_operand" "ri")))
  1178.    (set (pc)
  1179.     (if_then_else (match_operator:SI 3 "signed_comparison"
  1180.              [(cc0) (const_int 0)])
  1181.               (label_ref (match_operand 4 "" ""))
  1182.               (pc)))]
  1183.   "(GET_CODE (operands[2]) == CONST_INT
  1184.     ? (unsigned)INTVAL (operands[2]) + 32 >= 64
  1185.     : 1) && (rtx_equal_p (operands[0], operands[1])
  1186.          || rtx_equal_p (operands[0], operands[2]))"
  1187.   "*
  1188.   if (rtx_equal_p (operands[0], operands[1]))
  1189.     {
  1190.       output_asm_insn (\"dcmpw %2,%0\", operands);
  1191.       return \"b%N3 %l4\";
  1192.     }
  1193.   else
  1194.     {
  1195.       output_asm_insn (\"dcmpw %1,%0\", operands);
  1196.       return \"b%R3 %l4\";
  1197.     }
  1198. ")
  1199.  
  1200. (define_peephole
  1201.   [(set (match_operand:SI 0 "register_operand" "=r")
  1202.     (plus:SI (match_dup 0)
  1203.          (const_int 1)))
  1204.    (set (cc0)
  1205.     (compare (match_operand:SI 1 "register_operand" "r")
  1206.          (match_operand:SI 2 "nonmemory_operand" "ri")))
  1207.    (set (pc)
  1208.     (if_then_else (match_operator:SI 3 "signed_comparison"
  1209.              [(cc0) (const_int 0)])
  1210.               (label_ref (match_operand 4 "" ""))
  1211.               (pc)))]
  1212.   "(GET_CODE (operands[2]) == CONST_INT
  1213.     ? (unsigned)INTVAL (operands[2]) + 32 >= 64
  1214.     : 1) && (rtx_equal_p (operands[0], operands[1])
  1215.          || rtx_equal_p (operands[0], operands[2]))"
  1216.   "*
  1217.   if (rtx_equal_p (operands[0], operands[1]))
  1218.     {
  1219.       output_asm_insn (\"icmpw %2,%0\", operands);
  1220.       return \"b%N3 %l4\";
  1221.     }
  1222.   else
  1223.     {
  1224.       output_asm_insn (\"icmpw %1,%0\", operands);
  1225.       return \"b%R3 %l4\";
  1226.     }
  1227. ")
  1228.  
  1229. ;; Combine two word moves with consecutive operands into one long move.
  1230. ;; Also combines immediate moves, if the high-order destination operand
  1231. ;; is loaded with 0 or -1 and the low-order destination operand is loaded
  1232. ;; with a constant with the same sign.
  1233.  
  1234. (define_peephole
  1235.   [(set (match_operand:SI 0 "general_operand" "=g")
  1236.     (match_operand:SI 1 "general_operand" "g"))
  1237.    (set (match_operand:SI 2 "general_operand" "=g")
  1238.     (match_operand:SI 3 "general_operand" "g"))]
  1239.   "movdi_possible (operands)"
  1240.   "*
  1241. {
  1242.   output_asm_insn (\"# COMBINE movw %1,%0\", operands);
  1243.   output_asm_insn (\"# COMBINE movw %3,%2\", operands);
  1244.   movdi_possible (operands);
  1245.   if (CONSTANT_P (operands[1]))
  1246.     return (swap_operands ? \"movl %3,%0\" : \"movl %1,%2\");
  1247.  
  1248.   return (swap_operands ? \"movl %1,%0\" : \"movl %3,%2\");
  1249. }")
  1250.  
  1251. ;; Optimize certain tests after memory stores.
  1252.  
  1253. (define_peephole
  1254.   [(set (match_operand 0 "memory_operand" "=m")
  1255.     (match_operand 1 "register_operand" "r"))
  1256.    (set (match_operand:SI 2 "register_operand" "=r")
  1257.     (sign_extend:SI (match_dup 1)))
  1258.    (set (cc0)
  1259.     (match_dup 2))]
  1260.   "dead_or_set_p (insn, operands[2])"
  1261.   "*
  1262.   cc_status.flags |= CC_NO_OVERFLOW;
  1263.   if (GET_MODE (operands[0]) == QImode)
  1264.     return \"cvtwb %1,%0\";
  1265.   else
  1266.     return \"cvtwh %1,%0\";
  1267. ")
  1268.  
  1269. ;______________________________________________________________________
  1270. ;
  1271. ;    DImode Patterns.
  1272. ;______________________________________________________________________
  1273.  
  1274. (define_expand "extendsidi2"
  1275.   [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
  1276.     (match_operand:SI 1 "general_operand" "g"))
  1277.    (set (subreg:SI (match_dup 0) 0)
  1278.     (subreg:SI (match_dup 0) 1))
  1279.    (set (subreg:SI (match_dup 0) 0)
  1280.     (ashiftrt:SI (subreg:SI (match_dup 0) 0)
  1281.              (const_int 31)))]
  1282.   ""
  1283.   "")
  1284.  
  1285. (define_insn "adddi3"
  1286.   [(set (match_operand:DI 0 "register_operand" "=r")
  1287.     (plus:DI (match_operand:DI 1 "nonmemory_operand" "%0")
  1288.          (match_operand:DI 2 "nonmemory_operand" "rF")))]
  1289.   ""
  1290.   "*
  1291. {
  1292.   rtx xoperands[2];
  1293.   CC_STATUS_INIT;
  1294.   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1295.   if (REG_P (operands[2]))
  1296.     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
  1297.   else
  1298.     {
  1299.       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
  1300.                   CONST_DOUBLE_LOW (operands[2]));
  1301.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1302.                  CONST_DOUBLE_HIGH (operands[2]));
  1303.     }
  1304.   output_asm_insn (\"addw %1,%0\", xoperands);
  1305.   return \"addwc %2,%0\";
  1306. }")
  1307.  
  1308. (define_insn "subdi3"
  1309.   [(set (match_operand:DI 0 "register_operand" "=r")
  1310.     (minus:DI (match_operand:DI 1 "register_operand" "0")
  1311.           (match_operand:DI 2 "nonmemory_operand" "rF")))]
  1312.   ""
  1313.   "*
  1314. {
  1315.   rtx xoperands[2];
  1316.   CC_STATUS_INIT;
  1317.   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1318.   if (REG_P (operands[2]))
  1319.     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
  1320.   else
  1321.     {
  1322.       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
  1323.                   CONST_DOUBLE_LOW (operands[2]));
  1324.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1325.                  CONST_DOUBLE_HIGH (operands[2]));
  1326.     }
  1327.   output_asm_insn (\"subw %1,%0\", xoperands);
  1328.   return \"subwb %2,%0\";
  1329. }")
  1330.  
  1331. (define_insn "iordi3"
  1332.   [(set (match_operand:DI 0 "register_operand" "=r")
  1333.     (ior:DI (match_operand:DI 1 "nonmemory_operand" "%0")
  1334.         (match_operand:DI 2 "nonmemory_operand" "rF")))]
  1335.   ""
  1336.   "*
  1337. {
  1338.   rtx xoperands[2];
  1339.   CC_STATUS_INIT;
  1340.   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1341.   if (REG_P (operands[2]))
  1342.     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
  1343.   else
  1344.     {
  1345.       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
  1346.                   CONST_DOUBLE_LOW (operands[2]));
  1347.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1348.                  CONST_DOUBLE_HIGH (operands[2]));
  1349.     }
  1350.   output_asm_insn (\"orw %1,%0\", xoperands);
  1351.   return \"orw %2,%0\";
  1352. }")
  1353.  
  1354. (define_insn "anddi3"
  1355.   [(set (match_operand:DI 0 "register_operand" "=r")
  1356.     (and:DI (match_operand:DI 1 "nonmemory_operand" "%0")
  1357.         (match_operand:DI 2 "nonmemory_operand" "rF")))]
  1358.   ""
  1359.   "*
  1360. {
  1361.   rtx xoperands[2];
  1362.   CC_STATUS_INIT;
  1363.   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1364.   if (REG_P (operands[2]))
  1365.     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
  1366.   else
  1367.     {
  1368.       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
  1369.                   CONST_DOUBLE_LOW (operands[2]));
  1370.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1371.                  CONST_DOUBLE_HIGH (operands[2]));
  1372.     }
  1373.   output_asm_insn (\"andw %1,%0\", xoperands);
  1374.   return \"andw %2,%0\";
  1375. }")
  1376.  
  1377. (define_insn "xordi3"
  1378.   [(set (match_operand:DI 0 "register_operand" "=r")
  1379.     (xor:DI (match_operand:DI 1 "nonmemory_operand" "%0")
  1380.         (match_operand:DI 2 "nonmemory_operand" "rF")))]
  1381.   ""
  1382.   "*
  1383. {
  1384.   rtx xoperands[2];
  1385.   CC_STATUS_INIT;
  1386.   xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1387.   if (REG_P (operands[2]))
  1388.     xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
  1389.   else
  1390.     {
  1391.       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
  1392.                   CONST_DOUBLE_LOW (operands[2]));
  1393.       operands[2] = gen_rtx (CONST_INT, VOIDmode,
  1394.                  CONST_DOUBLE_HIGH (operands[2]));
  1395.     }
  1396.   output_asm_insn (\"xorw %1,%0\", xoperands);
  1397.   return \"xorw %2,%0\";
  1398. }")
  1399.  
  1400. ;; My version, modelled after Jonathan Stone's and "tablejump" - S.P.
  1401. (define_insn "indirect_jump"
  1402.   [(set (pc) (match_operand:SI 0 "general_operand" "r"))]
  1403.   ""
  1404.   "jump (%0)")
  1405.